home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / kxc / towns_os / pics / pics.c < prev    next >
Text File  |  1991-10-18  |  10KB  |  451 lines

  1. /*
  2.  *    PIC file saver coded by "C"
  3.  *    1989-9 ver 0.00  by Akira-Y.
  4.  *    1990.09.04 TOWNS版 Ver 0.1 by MSどす
  5.  *    1991.01.12 TOWNS版 Ver 0.21 by KXC KAROU・UOTA
  6.  *    1991.01.23 TOWNS版 Ver 0.22 by KXC KAROU・UOTA
  7.  *    1991.01.23 TOWNS版 Ver 0.23 by KXC KAROU・UOTA
  8.  *
  9.  *     Ver 0.1,及び0.22で色調が落ちる障害を無
  10.  *     くしました。
  11.  *     MS-DOSではレイヤ0に各種グラフィックを表示後、
  12.  *    コマンドライン上で、
  13.  *        RUN386 PICS [X Y X' Y'] FILENAME
  14.  *    と入力して下さい。
  15.  *     T-MENUからは、各ローダーと組にしたバッチファイル
  16.  *    で御使用下さい。
  17.  *
  18.  *    画面モード9、10、11のみで使用可能です。
  19.  *    画面サイズは仮想領域のフルサイズ(512×256)
  20.  *    迄対応しており、デフォルトのセーブ領域が、
  21.  *        (0,0)-(511,255)
  22.  *    となっております。
  23.  *    画面モード17の、512×512ドットモードをベー
  24.  *    スにする際は、
  25.  *        HS_psetm10
  26.  *        HS_pointm10
  27.  *    各々のセグメントの値を書換え、
  28.  *        header_write()
  29.  *    上記ルーチンのPICのヘッダフォーマットを512×
  30.  *    512迄のX6(標準PICフォーマット)とTOWN
  31.  *    Sの各モード値に変更して下さい。それ以外の値は使用
  32.  *    しないで下さい。
  33.  *
  34.  *
  35.  */
  36.  
  37. pragma    on ( Align_members ) ;
  38. pragma    on ( Align_all_labels ) ;
  39. pragma    on ( Align_labels ) ;
  40. pragma    on ( Align_routines ) ;
  41.  
  42. #include    <stdio.h>
  43. #include    <stdlib.h>
  44. #include    <egb.h>
  45.  
  46. #define SHORT   short int
  47. #define USHORT  unsigned short int
  48. #define UCHAR   unsigned char
  49. #define LONG    long
  50.  
  51. /*---------- Please rewrite --------------------------------------------*/
  52. #define        SIZE_OF_X 512        /* your screen X max        */
  53. #define        SIZE_OF_Y 256        /* your screen Y max        */
  54. /*----------------------------------------------------------------------*/
  55. #define        SIZE_OF_BUFF 512*256*2    /* file write buff size
  56.                      * you can change this parameter
  57.                      * value limit is 1 ~ max(integer)
  58.                      */
  59.  
  60. FILE    *fp ;
  61.  
  62. int    bit_length,            /* *buff_p effective bit length    */
  63.     buff_length,            /* buff rest            */
  64.     x0,x1,y0,y1;            /* (x0,y0)-(x1,y1) save area    */
  65.  
  66. char    *buff_p,            /* buff's read pointer        */
  67.     buff[SIZE_OF_BUFF];        /* file read buff        */
  68.  
  69. struct    {                /* for use color cash table    */
  70.     int    color;            /* dual LIST struct        */
  71.     int    next;
  72.     int    prev;
  73. }     table[128];
  74. int    color_p;            /*index for new color cash table*/
  75.  
  76. void    diff_point_mark(),        /* diff. point marking        */
  77.     header_write(),            /* pic file header write    */
  78.     press(),            /* compress routine        */
  79.     press_chain(),            /* chain data write        */
  80.     write_length(),            /* diff. point length write    */
  81.     write_color(),            /* color code write        */
  82.     color_cash_init(),        /* color cash table init.    */
  83.     new_color(),            /* set new color to table    */
  84.     set_color(),            /* change top of table        */
  85.     bit_write(),            /*  n bits write to file    */
  86.     buff_next_w(),            /* pointer next and write    */
  87.     buff_flush(),            /* write buff flush        */
  88.     error(),            /* error mess type and exit    */
  89.     pset() ;            /* put color to graphic ram    */
  90.  
  91. int    point(),            /* get color from graphic ram    */
  92.     search_col();            /* search color code from table */
  93.  
  94. extern    void HS_psetm10( int x,int y,int color ) ;
  95. extern    int  HS_pointm10( int x,int y ) ;
  96.  
  97.  
  98. /*
  99.  * main procedure of pic saver
  100.  *
  101.  */
  102. void
  103. main(argc, argv)
  104. int    argc;
  105. char    **argv;
  106. {
  107.     char    *file;
  108.  
  109.     if (argc != 2 && argc != 6) {
  110.         error("usage : pics [x y x' y'] <file>");
  111.     }
  112.     if (argc == 6) {
  113.         x0 = atoi(argv[1]);
  114.         y0 = atoi(argv[2]);
  115.         x1 = atoi(argv[3]);
  116.         y1 = atoi(argv[4]);
  117.         file = argv[5];
  118.         if (x0 > x1 || y0 > y1 || x1 >= SIZE_OF_X || y1 >= SIZE_OF_Y) {
  119.             error( "size over" ) ;
  120.         }
  121.     } else {
  122.         x0 = y0 = 0 ;
  123.         x1 = SIZE_OF_X - 1 ;
  124.         y1 = SIZE_OF_Y - 1 ;
  125.         file = argv[1] ;
  126.     }
  127.  
  128.     if ( (fp = fopen(file,"wb")) == NULL ){
  129.         error("file can not open") ;    /* ERROR */
  130.     }
  131.  
  132.     buff_p = buff ;            /* file pointer etc. initialize */
  133.     buff_length = SIZE_OF_BUFF ;
  134.     bit_length = 8 ;
  135.  
  136.     color_cash_init() ;    /* color cash table init.    */
  137.     header_write() ;    /* pic file header write    */
  138.     diff_point_mark() ;    /* color diff. point marking    */
  139.     press() ;        /* compress exec.        */
  140.     buff_flush() ;        /* write buff flush        */
  141.     fclose( fp ) ;
  142. }
  143.  
  144. void
  145. diff_point_mark()
  146. {
  147.     int    x,y,c,a ;
  148.  
  149.     c = 0 ;                /* 1st. color = 0 */
  150.     for ( y = y0 ; y <= y1 ; y++ ) {
  151.         for ( x = x0 ; x <= x1 ; x++ ) {
  152.             if ((a = (point(x, y) & 0x7fff)) != c) {
  153.                 c = a ;
  154.                 pset( x,y,( c|0x8000 )); /* lsb mark */
  155.             } else {
  156.                 pset( x,y,a ) ;     /* lsb clr */
  157.             }
  158.         }
  159.     }
  160. }
  161.  
  162. void
  163. header_write()
  164. {
  165.     bit_write( 8, (LONG)'P');        /* write ID    */
  166.     bit_write( 8, (LONG)'I');
  167.     bit_write( 8, (LONG)'C');
  168.     bit_write( 8, (LONG)26 );        /* text eof    */
  169.     bit_write( 8, (LONG)0  );        /* separater    */
  170.                         /* mode        */
  171.     bit_write(16, (LONG)0x0052 );        /* TOWNS_mode    */
  172.     bit_write(16, (LONG)15 );        /* color lenght */
  173.     bit_write(16, (LONG)(x1 - x0 + 1));    /* width of x    */
  174.     bit_write(16, (LONG)(y1 - y0 + 1));    /* width of y    */
  175. }
  176.  
  177. void
  178. press()
  179. {
  180.     LONG    l ;    /* for diff. length */
  181.     int    x, y, a;
  182.  
  183.     l = 0;
  184.     for (y = y0; y <= y1; y++) {
  185.         for (x = x0; x <= x1; x++) {
  186.             ++l ;
  187.             if ((a = point(x, y)) & 0x8000) {/* find mark point */
  188.                 write_length(l);
  189.                 write_color(a);
  190.                 press_chain(x, y, a);
  191.                 pset(x, y,( a&0x7fff ));
  192.                 l = 0;
  193.             }
  194.         }
  195.     }
  196.     write_length(l + 1);    /* end data */
  197.     bit_write(8, (LONG)0);    /* オマケだけど必要 */
  198. }
  199.  
  200. void
  201. press_chain(x, y, c)
  202. int    x, y, c;
  203. {
  204.     int    yy, d, f;
  205.  
  206.     f = 0;    /* chain exist flag */
  207.     for (yy = y + 1; yy <= y1; yy++) {
  208.         if (                       point(x, yy) == c) d = 2;
  209.         else if (   --x   >= x0 && point(x, yy) == c) d = 1;
  210.         else if ((x += 2) <= x1 && point(x, yy) == c) d = 3;
  211.         else if ((x -= 3) >= x0 && point(x, yy) == c) d = 4;
  212.         else if ((x += 4) <= x1 && point(x, yy) == c) d = 5;
  213.         else break ;
  214.         pset(x, yy,( c&0x7fff )) ;
  215.  
  216.         if (f == 0) bit_write(1, (LONG)1);
  217.         if (d == 4) bit_write(4, (LONG)2);
  218.         else if (d == 5) bit_write(4, (LONG)3);
  219.         else if (d <= 3) bit_write(2, (LONG)d);
  220.         f = 1;
  221.     }
  222.     if (f == 0) bit_write(1, (LONG)0);
  223.     else        bit_write(3, (LONG)0);
  224. }
  225.  
  226. void
  227. write_length(n)
  228. LONG    n;
  229. {
  230.     int    a;
  231.     LONG    b;
  232.  
  233.     a = 1 ;
  234.     b = 4 ;
  235.     while (n > b - 2) {
  236.         ++a ;
  237.         b <<= 1 ;
  238.     }
  239.     bit_write(a, 0xfffffffe);    /* lsb = 0 , other 31bit = 1 */
  240.     bit_write(a, (LONG)(n + 1 - b / 2));
  241. }
  242.  
  243. void
  244. write_color(c)
  245. int    c;
  246. {
  247.     int    a;
  248.  
  249.     if ((a = search_col( c )) != -1) {    /* color exist table ? */
  250.         bit_write(8, (LONG)( a+128 )) ;    /* color table's index */
  251.     } else {
  252. /*        bit_write(16, (LONG)((unsigned int)c / 2));***********/
  253.         bit_write(16, (LONG)((unsigned int)c & 0x7fff));
  254.     }
  255. }
  256.     
  257. int
  258. search_col(c)
  259. int    c ;
  260. {
  261.     int    i ;
  262.  
  263.     c &= 0x07fff ;
  264.     for ( i = 0 ; i < 128 ; i++ ) {
  265.         if ( table[i].color == c )
  266.             break ;
  267.     }
  268.     if ( i == 128 ) {
  269.         new_color( c ) ;
  270.         return( -1 ) ;
  271.     } else {
  272.         set_color( i ) ;
  273.         return( i ) ;
  274.     }
  275. }
  276.  
  277. void
  278. color_cash_init()
  279. {
  280.     int    i ;
  281.  
  282.     for ( i = 0; i < 128; i++ ) {
  283.         table[i].color = 0;
  284.         table[i].prev = i + 1;
  285.         table[i].next = i - 1;
  286.     }
  287.     table[127].prev = 0;
  288.     table[0].next = 127;
  289.     color_p = 0;
  290. }
  291.  
  292. void
  293. new_color(c)
  294. int    c;
  295. {
  296.     color_p = table[color_p].prev;
  297.     table[color_p].color = c;
  298. }
  299.  
  300. void
  301. set_color( idx )
  302. int    idx ;
  303. {
  304.     if ( color_p != idx ) {
  305.         /* idx take off from table */
  306.         table[table[idx].prev].next = table[idx].next;
  307.         table[table[idx].next].prev = table[idx].prev;
  308.  
  309.         /* idx set to new table point*/
  310.         table[table[color_p].prev].next = idx;
  311.         table[idx].prev = table[color_p].prev;  
  312.         table[color_p].prev = idx;
  313.         table[idx].next = color_p;
  314.         color_p = idx;
  315.     }
  316. }
  317.  
  318. /*
  319.  * size bits write for file
  320.  *
  321.  */
  322.  
  323. void
  324. bit_write(size, n)
  325. SHORT    size;
  326. LONG    n;
  327. {
  328.     int    i ;
  329.     int    mask ;
  330.  
  331.     mask = ( 1<<size )-1 ;
  332.     n &= mask;
  333.     
  334.     n <<= ( 32-size ) ;
  335.     while (size > bit_length) {
  336.         for (i = 0; i < bit_length; i++) {
  337. /*            *buff_p = *buff_p + *buff_p + (n < 0);*/
  338.             *buff_p <<= 1;
  339.             *buff_p += ((n & 0x80000000) ? 1 : 0);
  340.                 /* if n's msb is set then +1 */
  341. /*            n = n + n;
  342.             size = size - 1;*/
  343.             n <<= 1 ;
  344.             --size ;
  345.         }
  346.         buff_next_w();
  347.     }
  348.     for (i = 0; i < size; i++) {
  349. /*        *buff_p = *buff_p + *buff_p + (n < 0);*/
  350.         *buff_p <<= 1;
  351.         *buff_p += ((n & 0x80000000) ? 1 : 0);
  352.             /* if n's msb is set then +1 */
  353. /*        n = n + n;
  354.         bit_length = bit_length - 1;*/
  355.         n <<= 1 ;
  356.         bit_length-- ;
  357.     }
  358. }
  359.  
  360. /*
  361.  * buff pointer inc. and write next buff
  362.  */
  363. void
  364. buff_next_w()
  365. {
  366.     if (--buff_length == 0) {
  367.         if (fwrite(buff,1, SIZE_OF_BUFF,fp) != SIZE_OF_BUFF) {
  368.             error("file write error buff_next_w");
  369.         }
  370.         buff_p = buff;
  371.         buff_length = SIZE_OF_BUFF;
  372.     } else {
  373.         ++buff_p;
  374.     }
  375.     bit_length = 8;
  376. }
  377.  
  378. void
  379. buff_flush()
  380. {
  381.     if (bit_length > 0) {
  382.         *buff_p <<= bit_length;
  383.         buff_next_w();
  384.     }
  385.     buff_length = SIZE_OF_BUFF - buff_length;
  386.     if (buff_length > 0) {
  387.         if (fwrite(buff,1, buff_length,fp) != buff_length){
  388.             error("file write error buff_flush");
  389.         }
  390.     }
  391. }
  392.  
  393. void
  394. error( s )
  395. char    *s ;
  396. {
  397.  
  398.     {    /* 本複文は,デバッグ用ダンプとして使用可 */
  399.         printf("%s", s);
  400. /**
  401.         DISP_stringRect(buf, CI_Blue, CI_Gray);
  402.         MOU_waitClick(MouseLeftButton);
  403.         MOU_waitRelease(MouseLeftButton, &x, &y);
  404. ***/
  405.     }
  406.     exit(1);
  407. }
  408.  
  409. int    point( x,y )
  410. int    x,y ;
  411. {
  412.     return( HS_pointm10( x,y )) ;
  413. }
  414.  
  415. /*---------- Please rewrite --------------------------------------------
  416.  *
  417.  * c = point( x,y )
  418.  * dot get to graphic screen
  419.  *
  420.  * in
  421.  *    x : screen X (0~SIZE_OF_X-1)
  422.  *    y : screen Y (0~SIZE_OF_Y-1)
  423.  * out
  424.  *    c : color code 16bit
  425.  *        0     : bright
  426.  *        1..5  : blue
  427.  *        6..10 : red
  428.  *        11..15: green
  429.  */
  430.  
  431. /*---------- Please rewrite --------------------------------------------
  432.  *
  433.  * pset(x, y, c)
  434.  * dot set to graphic screen
  435.  *
  436.  * in
  437.  *    x : screen X (0~SIZE_OF_X-1)
  438.  *    y : screen Y (0~SIZE_OF_Y-1)
  439.  *    c : color code 16bit
  440.  *        0     : bright
  441.  *        1..5  : blue
  442.  *        6..10 : red
  443.  *        11..15: green
  444.  */
  445.  
  446. void    pset( x,y,color )
  447. int    x,y,color ;
  448. {
  449.     HS_psetm10( x,y,color ) ;
  450. }
  451.